home *** CD-ROM | disk | FTP | other *** search
- /* reflect.c */
-
- /*
- * Demo of a reflective, texture-mapped surface with OpenGL.
- * Brian Paul (brianp@ssec.wisc.edu) August 14, 1995
- *
- * Hardware texture mapping is highly recommended!
- *
- * The basic steps are:
- * 1. Render the reflective object (a polygon) from the normal viewpoint,
- * setting the stencil planes = 1.
- * 2. Render the scene from a special viewpoint: the viewpoint which
- * is on the opposite side of the reflective plane. Only draw where
- * stencil = 1. This draws the objects in the reflective surface.
- * 3. Render the scene from the original viewpoint. This draws the
- * objects in the normal fashion. Use blending when drawing
- * the reflective, textured surface.
- *
- * This is a very crude demo. It could be much better.
- */
-
- /*
- * Dirk Reiners (reiners@igd.fhg.de) made some modifications to this code.
- *
- * August 1996 - A few optimizations by Brian
- */
-
-
-
- #define USE_ZBUFFER
-
-
- /* OK, without hardware support this is overkill. */
- #define USE_TEXTURE
-
- #include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "gltk.h"
-
-
- #define DEG2RAD (3.14159/180.0)
-
-
- #define TABLE_TEXTURE "../samples/1.rgb"
-
-
- #define MAX_OBJECTS 2
-
- static GLint table_list;
- static GLint objects_list[MAX_OBJECTS];
-
-
- static GLfloat xrot, yrot;
- static GLfloat spin;
-
-
-
- static void make_table( void )
- {
- static GLfloat table_mat[] = { 1.0, 1.0, 1.0, 0.6 };
- static GLfloat gray[] = { 0.4, 0.4, 0.4, 1.0 };
-
- table_list = glGenLists(1);
- glNewList( table_list, GL_COMPILE );
-
- /* load table's texture */
- glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, table_mat );
- /* glMaterialfv( GL_FRONT, GL_EMISSION, gray );*/
- glMaterialfv( GL_FRONT, GL_DIFFUSE, table_mat );
- glMaterialfv( GL_FRONT, GL_AMBIENT, gray );
-
- /* draw textured square for the table */
- glPushMatrix();
- glScalef( 4.0, 4.0, 4.0 );
- glBegin( GL_POLYGON );
- glNormal3f( 0.0, 1.0, 0.0 );
- glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, 0.0, 1.0 );
- glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 1.0 );
- glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 0.0, -1.0 );
- glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, 0.0, -1.0 );
- glEnd();
- glPopMatrix();
-
- glDisable( GL_TEXTURE_2D );
-
- glEndList();
- }
-
-
- static void make_objects( void )
- {
- GLUquadricObj *q;
-
- static GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 };
- static GLfloat green[] = { 0.2, 1.0, 0.2, 1.0 };
- static GLfloat black[] = { 0.0, 0.0, 0.0, 0.0 };
-
- q = gluNewQuadric();
- gluQuadricDrawStyle( q, GLU_FILL );
- gluQuadricNormals( q, GLU_SMOOTH );
-
- objects_list[0] = glGenLists(1);
- glNewList( objects_list[0], GL_COMPILE );
- glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan );
- glMaterialfv( GL_FRONT, GL_EMISSION, black );
- gluCylinder( q, 0.5, 0.5, 1.0, 15, 10 );
- glEndList();
-
- objects_list[1] = glGenLists(1);
- glNewList( objects_list[1], GL_COMPILE );
- glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
- glMaterialfv( GL_FRONT, GL_EMISSION, black );
- gluCylinder( q, 1.5, 0.0, 2.5, 15, 10 );
- glEndList();
- }
-
-
-
- static void init( void )
- {
- static GLfloat light_pos[] = { 0.0, 0.0, 20.0, 1.0 };
- TK_RGBImageRec *image;
-
- make_table();
- make_objects();
-
- /* Setup texture */
- #ifdef USE_TEXTURE
- image = tkRGBImageLoad( TABLE_TEXTURE );
- gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image->sizeX, image->sizeY,
- GL_RGB, GL_UNSIGNED_BYTE, image->data);
-
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
- #endif
-
-
- xrot = 30.0;
- yrot = 50.0;
- spin = 0.0;
-
- #ifndef USE_ZBUFFER
- glEnable( GL_CULL_FACE );
- #endif
-
- glShadeModel( GL_FLAT );
-
- glEnable( GL_LIGHT0 );
- glEnable( GL_LIGHTING );
-
- glLightfv( GL_LIGHT0, GL_POSITION, light_pos );
-
- glClearColor( 0.5, 0.5, 0.5, 1.0 );
-
- glEnable( GL_NORMALIZE );
- }
-
-
-
- static void reshape(int w, int h)
- {
- GLfloat aspect = (float) w / (float) h;
-
- glViewport(0, 0, w, h);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glFrustum( -aspect, aspect, -1.0, 1.0, 4.0, 300.0 );
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- }
-
-
-
- static void draw_objects( GLfloat eyex, GLfloat eyey, GLfloat eyez )
- {
- #ifndef USE_ZBUFFER
- if (eyex<0.5)
- {
- #endif
- glPushMatrix();
- glTranslatef( 1.0, 1.5, 0.0 );
- glRotatef( spin, 1.0, 0.5, 0.0 );
- glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
- glCallList( objects_list[0] );
- glPopMatrix();
-
- glPushMatrix();
- glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
- glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
- glRotatef( spin, 1.0, 0.5, 0.0 );
- glScalef( 0.5, 0.5, 0.5 );
- glCallList( objects_list[1] );
- glPopMatrix();
- #ifndef USE_ZBUFFER
- }
- else
- {
- glPushMatrix();
- glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
- glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
- glRotatef( spin, 1.0, 0.5, 0.0 );
- glScalef( 0.5, 0.5, 0.5 );
- glCallList( objects_list[1] );
- glPopMatrix();
-
- glPushMatrix();
- glTranslatef( 1.0, 1.5, 0.0 );
- glRotatef( spin, 1.0, 0.5, 0.0 );
- glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
- glCallList( objects_list[0] );
- glPopMatrix();
- }
- #endif
- }
-
-
-
- static void draw_table( void )
- {
- glCallList( table_list );
- }
-
-
-
- static void draw_scene( void )
- {
- GLfloat dist = 20.0;
- GLfloat eyex, eyey, eyez;
-
- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-
-
- eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
- eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
- eyey = dist * sin(xrot*DEG2RAD);
-
- /* view from top */
- glPushMatrix();
- gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );
-
-
- /* draw table into stencil planes */
- glEnable( GL_STENCIL_TEST );
- #ifdef USE_ZBUFFER
- glDisable( GL_DEPTH_TEST );
- #endif
- glStencilFunc( GL_ALWAYS, 1, 0xffffffff );
- glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
- glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
- draw_table();
- glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
-
- #ifdef USE_ZBUFFER
- glEnable( GL_DEPTH_TEST );
- #endif
-
-
- /* render view from below (reflected viewport) */
- /* only draw where stencil==1 */
- if (eyey>0.0) {
- glPushMatrix();
-
- glStencilFunc( GL_EQUAL, 1, 0xffffffff ); /* draw if ==1 */
- glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
- glScalef( 1.0, -1.0, 1.0 );
- draw_objects(eyex, eyey, eyez);
- glPopMatrix();
- }
-
- glDisable( GL_STENCIL_TEST );
-
- glEnable( GL_BLEND );
- glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
-
- #ifdef USE_TEXTURE
- glEnable( GL_TEXTURE_2D );
- #endif
- draw_table();
- glDisable( GL_TEXTURE_2D );
- glDisable( GL_BLEND );
-
- /* view from top */
- glPushMatrix();
-
- draw_objects(eyex, eyey, eyez);
-
- glPopMatrix();
-
- glPopMatrix();
-
- tkSwapBuffers();
- }
-
-
-
- #if 0
- void draw_scene(void)
- {
- GLfloat dist = 20.0;
- GLfloat eyex, eyey, eyez;
-
- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-
-
- eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
- eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
- eyey = dist * sin(xrot*DEG2RAD);
-
- /* view from top */
- glPushMatrix();
- gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );
-
- draw_table();
-
- glPopMatrix();
-
- tkSwapBuffers();
- }
- #endif
-
-
- GLenum key( int key, GLenum mask )
- {
- switch (key) {
- case 27:
- exit(0);
- break;
-
- case TK_UP:
- xrot += 3.0;
- #ifndef USE_ZBUFFER
- if ( xrot > 180 ) xrot = 180;
- #endif
- break;
- case TK_DOWN:
- xrot -= 3.0;
- #ifndef USE_ZBUFFER
- if ( xrot < 0 ) xrot = 0;
- #endif
- break;
- case TK_LEFT:
- yrot += 3.0;
- break;
- case TK_RIGHT:
- yrot -= 3.0;
- break;
- }
- return 0;
- }
-
-
-
- static void idle( void )
- {
- spin += 2.0;
- yrot += 3.0;
- draw_scene();
- }
-
-
-
- int main( int argc, char *argv[] )
- {
- tkInitDisplayMode(TK_DOUBLE | TK_RGB
- #ifdef USE_ZBUFFER
- | TK_DEPTH
- #endif
- | TK_STENCIL);
- tkInitPosition( 0, 0, 400, 300 );
- tkInitWindow(argv[0]);
- tkReshapeFunc(reshape);
- tkDisplayFunc(draw_scene);
- tkKeyDownFunc(key);
- tkIdleFunc(idle);
-
- init();
-
- tkExec();
- return 0;
- }
-